home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Graphics⁄Sound / RTrace-1.0-src / patch_3.c < prev    next >
Text File  |  1992-09-17  |  5KB  |  150 lines

  1. /*
  2.  * Copyright (c) 1988, 1992 Antonio Costa, INESC-Norte.
  3.  * All rights reserved.
  4.  *
  5.  * This code received contributions from the following people:
  6.  *
  7.  *  Roman Kuchkuda      - basic ray tracer
  8.  *  Mark VandeWettering - MTV ray tracer
  9.  *  Augusto Sousa       - overall, shading model
  10.  *
  11.  * Redistribution and use in source and binary forms are permitted
  12.  * provided that the above copyright notice and this paragraph are
  13.  * duplicated in all such forms and that any documentation,
  14.  * advertising materials, and other materials related to such
  15.  * distribution and use acknowledge that the software was developed
  16.  * by Antonio Costa, at INESC-Norte. The name of the author and
  17.  * INESC-Norte may not be used to endorse or promote products derived
  18.  * from this software without specific prior written permission.
  19.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  21.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  22.  */
  23. #include "defs.h"
  24. #include "extern.h"
  25.  
  26. /**********************************************************************
  27.  *    RAY TRACING - Patch (part1) - Version 7.3.2                     *
  28.  *                                                                    *
  29.  *    MADE BY    : Antonio Costa, INESC-Norte, October 1988           *
  30.  *    ADAPTED BY : Antonio Costa, INESC-Norte, June 1989              *
  31.  *    MODIFIED BY: Antonio Costa, INESC-Norte, August 1992            *
  32.  **********************************************************************/
  33.  
  34. /***** Patch *****/
  35. #include "patch.h"
  36.  
  37. static real     small_distance;
  38. static xyz_struct k0, k1, k2, k3, k4, k5, k6, k7, p[4];
  39. static patch_ptr patch;
  40.  
  41. real
  42. patch_intersect(position, vector, object)
  43.   xyz_ptr         position, vector;
  44.   object_ptr      object;
  45. {
  46.   REG real        u, v, b0, b1, b2, b3, distance;
  47.   xyz_struct      p0, p1, p2, p3, p4, p5, p6, p7, p8, pmin, pmax;
  48.  
  49.   REALINC(patch_tests);
  50.   patch = (patch_ptr) object->data;
  51.   STRUCT_ASSIGN(p[0], patch->p[3]->coords);
  52.   STRUCT_ASSIGN(p[1], patch->p[4]->coords);
  53.   STRUCT_ASSIGN(p[2], patch->p[7]->coords);
  54.   STRUCT_ASSIGN(p[3], patch->p[8]->coords);
  55.   STRUCT_ASSIGN(p0, p[0]);
  56.   STRUCT_ASSIGN(p2, p[1]);
  57.   STRUCT_ASSIGN(p6, p[2]);
  58.   STRUCT_ASSIGN(p8, p[3]);
  59.   /* Points 1 and 7 */
  60.   u = 0.5;
  61.   b0 = BLEND0(u);
  62.   b1 = BLEND1(u);
  63.   CUBIC(patch, 0, u, k0);
  64.   CUBIC(patch, 2, u, k2);
  65.   MULTIPLY(p[0], b0, k4);
  66.   MULTIPLY(p[1], b1, k5);
  67.   MULTIPLY(p[2], b0, k6);
  68.   MULTIPLY(p[3], b1, k7);
  69.   SUBTRACT(k0, k4, k5, k0);
  70.   SUBTRACT(k2, k6, k7, k2);
  71.   /* Point 1 */
  72.   v = 0.0;
  73.   CUBIC(patch, 1, v, k1);
  74.   CUBIC(patch, 3, v, k3);
  75.   b2 = BLEND0(v);
  76.   b3 = BLEND1(v);
  77.   p1.x = k0.x * b2 + k1.x * b0 + k2.x * b3 + k3.x * b1;
  78.   p1.y = k0.y * b2 + k1.y * b0 + k2.y * b3 + k3.y * b1;
  79.   p1.z = k0.z * b2 + k1.z * b0 + k2.z * b3 + k3.z * b1;
  80.   /* Point 7 */
  81.   v = 1.0;
  82.   CUBIC(patch, 1, v, k1);
  83.   CUBIC(patch, 3, v, k3);
  84.   b2 = BLEND0(v);
  85.   b3 = BLEND1(v);
  86.   p7.x = k0.x * b2 + k1.x * b0 + k2.x * b3 + k3.x * b1;
  87.   p7.y = k0.y * b2 + k1.y * b0 + k2.y * b3 + k3.y * b1;
  88.   p7.z = k0.z * b2 + k1.z * b0 + k2.z * b3 + k3.z * b1;
  89.   /* Points 3, 4 and 5 */
  90.   v = 0.5;
  91.   b0 = BLEND0(v);
  92.   b1 = BLEND1(v);
  93.   CUBIC(patch, 1, v, k1);
  94.   CUBIC(patch, 3, v, k3);
  95.   MULTIPLY(p[0], b0, k4);
  96.   MULTIPLY(p[1], b0, k5);
  97.   MULTIPLY(p[2], b1, k6);
  98.   MULTIPLY(p[3], b1, k7);
  99.   SUBTRACT(k1, k4, k6, k1);
  100.   SUBTRACT(k3, k5, k7, k3);
  101.   /* Point 3 */
  102.   u = 0.0;
  103.   CUBIC(patch, 0, u, k0);
  104.   CUBIC(patch, 2, u, k2);
  105.   b2 = BLEND0(u);
  106.   b3 = BLEND1(u);
  107.   p3.x = k0.x * b0 + k1.x * b2 + k2.x * b1 + k3.x * b3;
  108.   p3.y = k0.y * b0 + k1.y * b2 + k2.y * b1 + k3.y * b3;
  109.   p3.z = k0.z * b0 + k1.z * b2 + k2.z * b1 + k3.z * b3;
  110.   /* Point 4 */
  111.   u = 0.5;
  112.   CUBIC(patch, 0, u, k0);
  113.   CUBIC(patch, 2, u, k2);
  114.   b2 = BLEND0(u);
  115.   b3 = BLEND1(u);
  116.   p4.x = k0.x * b0 + k1.x * b2 + k2.x * b1 + k3.x * b3;
  117.   p4.y = k0.y * b0 + k1.y * b2 + k2.y * b1 + k3.y * b3;
  118.   p4.z = k0.z * b0 + k1.z * b2 + k2.z * b1 + k3.z * b3;
  119.   /* Point 5 */
  120.   u = 1.0;
  121.   CUBIC(patch, 0, u, k0);
  122.   CUBIC(patch, 2, u, k2);
  123.   b2 = BLEND0(u);
  124.   b3 = BLEND1(u);
  125.   p5.x = k0.x * b0 + k1.x * b2 + k2.x * b1 + k3.x * b3;
  126.   p5.y = k0.y * b0 + k1.y * b2 + k2.y * b1 + k3.y * b3;
  127.   p5.z = k0.z * b0 + k1.z * b2 + k2.z * b1 + k3.z * b3;
  128.   /* Intersect */
  129.   small_distance = INFINITY;
  130.   subpatch_enclose(&p0, &p1, &p3, &p4, &pmin, &pmax);
  131.   distance = bound_intersect(position, vector, &pmin, &pmax);
  132.   if ((distance > 0.0) AND(distance < small_distance))
  133.     patch_divide(&p0, &p1, &p3, &p4, 0.0, 0.0, 0.5, 1, position, vector);
  134.   subpatch_enclose(&p1, &p2, &p4, &p5, &pmin, &pmax);
  135.   distance = bound_intersect(position, vector, &pmin, &pmax);
  136.   if ((distance > 0.0) AND(distance < small_distance))
  137.     patch_divide(&p1, &p2, &p4, &p5, 0.5, 0.0, 0.5, 1, position, vector);
  138.   subpatch_enclose(&p3, &p4, &p6, &p7, &pmin, &pmax);
  139.   distance = bound_intersect(position, vector, &pmin, &pmax);
  140.   if ((distance > 0.0) AND(distance < small_distance))
  141.     patch_divide(&p3, &p4, &p6, &p7, 0.0, 0.5, 0.5, 1, position, vector);
  142.   subpatch_enclose(&p4, &p5, &p7, &p8, &pmin, &pmax);
  143.   distance = bound_intersect(position, vector, &pmin, &pmax);
  144.   if ((distance > 0.0) AND(distance < small_distance))
  145.     patch_divide(&p4, &p5, &p7, &p8, 0.5, 0.5, 0.5, 1, position, vector);
  146.   if (small_distance > INFINITY * 0.5)
  147.     return 0.0;
  148.   return small_distance;
  149. }
  150.